package com.kakaxi.mybilibili.net;

import android.content.Context;
import android.widget.ImageView;

import com.vincestyling.netroid.Listener;
import com.vincestyling.netroid.Network;
import com.vincestyling.netroid.Request;
import com.vincestyling.netroid.RequestQueue;
import com.vincestyling.netroid.cache.BitmapImageCache;
import com.vincestyling.netroid.cache.DiskCache;
import com.vincestyling.netroid.request.JsonRequest;
import com.vincestyling.netroid.stack.HurlStack;
import com.vincestyling.netroid.toolbox.BasicNetwork;
import com.vincestyling.netroid.toolbox.FileDownloader;
import com.vincestyling.netroid.toolbox.ImageLoader;
import com.vincestyling.netroid.widget.NetworkImageView;

import org.apache.http.protocol.HTTP;

import java.io.File;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.X509TrustManager;

/**
 * Netroid网络请求框架封装类
 * Created by kakaxi on 16/8/2.
 */
public class Netroid {

    /**
     * 默认缓存时间
     */
    public static int DEFAULT_CACHE_EXPIRE_TIME = 30;

    /**
     * 请求队列
     */
    private static RequestQueue mRequestQueue;

    /**
     * 图片加载管理器
     */
    private static ImageLoader mImageLoader;

    /**
     * 文件下载管理器
     */
    private static FileDownloader mFileDownloader;

    private Netroid() {
    }

    /**
     * 初始化请求队列,图片加载管理器,文件下载器等
     *
     * @param ctx 上下文类
     */
    public static void init(Context ctx) {
        if (mRequestQueue != null) throw new IllegalStateException("initialized");

        // 创建netroid主类,指定硬盘缓存方案
        Network network = new BasicNetwork(new HurlStack(Const.USER_AGENT, null), HTTP.UTF_8);
        mRequestQueue = new RequestQueue(network, RequestQueue.DEFAULT_NETWORK_THREAD_POOL_SIZE,
                new DiskCache(new File(ctx.getCacheDir(),
                        Const.HTTP_DISK_CACHE_DIR_NAME), Const.HTTP_DISK_CACHE_SIZE));

        // 创建图片加载管理器,指定硬盘缓存方案
        mImageLoader = new SelfImageLoader(mRequestQueue, new BitmapImageCache(Const
                .HTTP_MEMORY_CACHE_SIZE), ctx.getResources(), ctx.getAssets());

        mFileDownloader = new FileDownloader(mRequestQueue, 1);

        mRequestQueue.start();
    }

    /**
     * 销毁网络请求框架,由于都是静态变量因此需要进行销毁操作才能把静态参数从内存中销毁
     */
    public static void destory() {
        if (mRequestQueue != null) {
            mRequestQueue.stop();
            mRequestQueue = null;
        }
        if (mFileDownloader != null) {
            mFileDownloader.clearAll();
            mFileDownloader = null;
        }
        mImageLoader = null;
    }

    /**
     * 添加网络请求到请求队列中,并且设置缓存
     *
     * @param jsonRequest        json请求
     * @param cache              是否缓存
     * @param cacheExpireMinutes 缓存过期时长
     * @param forceUpdate        强制更新缓存
     */
    public static void addRequest(JsonRequest jsonRequest, boolean cache, int cacheExpireMinutes,
                                  boolean forceUpdate) {
//        SSLContext sslContext = null;
//        TrustManager[] trustManagers = new TrustManager[] {
//                new HTTPSTrustManager()
//        };
//        try {
//            sslContext = SSLContext.getInstance("TLS");
//            sslContext.init(null, trustManagers, new SecureRandom());
//        } catch (NoSuchAlgorithmException | KeyManagementException e) {
//            e.printStackTrace();
//        }
//        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
//        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
//            @Override
//            public boolean verify(String hostname, SSLSession session) {
//                return true;
//            }
//        });
//        HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
        if (cache) {
            jsonRequest.setForceUpdate(forceUpdate);
            jsonRequest.setCacheExpireTime(TimeUnit.MINUTES, cacheExpireMinutes);
        }
        mRequestQueue.add(jsonRequest);
    }

    /**
     * 添加网络请求到请求队列中,并且设置缓存
     *
     * @param jsonRequest json请求
     * @param cache       是否缓存
     * @param forceUpdate 强制更新缓存
     */
    public static void addRequest(JsonRequest jsonRequest, boolean cache,
                                  boolean forceUpdate) {
        addRequest(jsonRequest, cache, DEFAULT_CACHE_EXPIRE_TIME, forceUpdate);
    }

    /**
     * 添加网络请求到请求队列中,并且设置缓存
     *
     * @param jsonRequest json请求
     * @param cache       是否缓存
     */
    public static void addRequest(JsonRequest jsonRequest, boolean cache) {
        addRequest(jsonRequest, cache, DEFAULT_CACHE_EXPIRE_TIME, false);
    }

    /**
     * 添加网络请求到请求队列中
     *
     * @param jsonRequest json请求
     */
    public static void addRequest(JsonRequest jsonRequest) {
        addRequest(jsonRequest, false, -1, false);
    }

    /**
     * 添加网络请求到请求队列中,并且设置缓存
     *
     * @param request 请求
     * @param cache   是否缓存
     */
    public static void addRequest(Request request, boolean cache) {
        if (cache) {
            request.setCacheExpireTime(TimeUnit.MINUTES, DEFAULT_CACHE_EXPIRE_TIME);
        }
        mRequestQueue.add(request);
    }


    /**
     * 加载单张图片
     *
     * @param url       图片链接
     * @param imageView 图片控件
     */
    public static void displayImage(String url, ImageView imageView) {
        displayImage(url, imageView, 0, 0);
    }

    /**
     * 加载单张图片并且可以设置默认与出错时显示的图片
     *
     * @param url               图片链接
     * @param imageView         图片控件
     * @param defaultImageResId 默认显示图片的资源id
     * @param errorImageResId   出错图片的资源id
     */
    public static void displayImage(String url, ImageView imageView, int defaultImageResId, int
            errorImageResId) {
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView,
                defaultImageResId, errorImageResId);
        mImageLoader.get(url, listener, 0, 0);
    }

    /**
     * 批量加载图片
     *
     * @param url       图片链接
     * @param imageView 批量图片控件
     */
    public static void displayImage(String url, NetworkImageView imageView) {
        displayImage(url, imageView, 0, 0);
    }

    /**
     * 批量加载图片并且可以设置默认与出错时显示的图片
     *
     * @param url               图片链接
     * @param imageView         批量图片控件
     * @param defaultImageResId 默认显示图片的资源id
     * @param errorImageResId   出错图片的资源id
     */
    public static void displayImage(String url, NetworkImageView imageView, int
            defaultImageResId, int errorImageResId) {
        imageView.setDefaultImageResId(defaultImageResId);
        imageView.setErrorImageResId(errorImageResId);
        imageView.setImageUrl(url, mImageLoader);
    }

    /**
     * 执行文件下载请求
     *
     * @param storeFilePath 本地路径
     * @param url           文件链接
     * @param listener      文件下载监听器
     * @return
     */
    public static FileDownloader.DownloadController addFileDownload(String storeFilePath, String
            url, Listener<Void> listener) {
        return mFileDownloader.add(storeFilePath, url, listener);
    }

    class Const {
        /**
         * 2m的内存缓存
         */
        public static final int HTTP_MEMORY_CACHE_SIZE = 2 * 1024 * 1024;
        /**
         * 50m的本地缓存
         */
        public static final int HTTP_DISK_CACHE_SIZE = 50 * 1024 * 1024;
        /**
         * 缓存目录名
         */
        public static final String HTTP_DISK_CACHE_DIR_NAME = "netroid";
        /**
         * 请求的用户标志
         */
        public static final String USER_AGENT = "netroid.cn";

    }

    private static class HTTPSTrustManager implements X509TrustManager {

        private X509Certificate[] mAcceptedIssuers = new X509Certificate[]{};

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws
                CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws
                CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return mAcceptedIssuers;
        }

        public boolean isClientTrusted(X509Certificate[] chain) {
            return true;
        }

        public boolean isServerTrusted(X509Certificate[] chain) {
            return true;
        }

    }


}
